// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import {AvatarIcon} from 'chrome://resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.js';
import {sendWithPromise} from 'chrome://resources/js/cr.m.js';

/**
 * This is the data structure sent back and forth between C++ and JS.
 */
export type ProfileState = {
  profilePath: string,
  localProfileName: string,
  isSyncing: boolean,
  needsSignin: boolean,
  gaiaName: string,
  userName: string,
  isManaged: boolean,
  avatarIcon: string,
  // <if expr="lacros">
  isPrimaryLacrosProfile: boolean,
  // </if>
};

/**
 * This is the data structure sent back and forth between C++ and JS.
 * `colorId` has the following special values:
 *   - `-1` for the default theme.
 *   - `0` for a manually picked color theme.
 */
export type AutogeneratedThemeColorInfo = {
  colorId: number,
  color: number,
  themeFrameColor: string,
  themeShapeColor: string,
  themeFrameTextColor: string,
  themeGenericAvatar: string,
};

/**
 * This is the data structure sent back and forth between C++ and JS.
 * `colorId` has the following special values:
 *   - `-1` for the default theme..
 *   - `0` for a manually picked color theme
 * `color` is defined only for manually picked themes.
 */
export type UserThemeChoice = {
  colorId: number,
  color?: number,
};

// <if expr="lacros">
/**
 * This is a data structure sent from C++ to JS, representing accounts present
 * in the ChromeOS system, but not in any Lacros profile.
 */
export type AvailableAccount = {
  gaiaId: string,
  name: string,
  email: string,
  accountImageUrl: string,
};
// </if>

export interface ManageProfilesBrowserProxy {
  /**
   * Initializes profile picker main view.
   */
  initializeMainView(): void;

  /**
   * Launches picked profile and closes the profile picker.
   */
  launchSelectedProfile(profilePath: string): void;

  /**
   * Opens profile on manage profile settings sub page and closes the
   * profile picker.
   */
  openManageProfileSettingsSubPage(profilePath: string): void;

  /** Launches Guest profile. */
  launchGuestProfile(): void;

  /**
   * Inform native the user's choice on whether to show the profile picker
   * on startup or not.
   */
  askOnStartupChanged(shouldShow: boolean): void;

  /**
   * Retrieves suggested theme for the new profile.
   * @return A promise firing with the suggested theme info, once it has been
   *     retrieved.
   */
  getNewProfileSuggestedThemeInfo(): Promise<AutogeneratedThemeColorInfo>;

  /**
   * Retrieves all relevant theme information for the particular theme.
   * @param theme A theme which info needs to be retrieved.
   * @return A promise firing with the theme info, once it has been retrieved.
   */
  getProfileThemeInfo(theme: UserThemeChoice):
      Promise<AutogeneratedThemeColorInfo>;

  /**
   * Retrieves profile statistics to be shown in the remove profile warning.
   */
  getProfileStatistics(profilePath: string): void;

  /**
   * Removes profile.
   */
  removeProfile(profilePath: string): void;

  /**
   * Loads Google sign in page (and silently creates a profile with the
   * specified color and account, if specified).
   */
  loadSignInProfileCreationFlow(profileColor: number|null, gaiaId: string):
      void;

  /**
   * Retrieves custom avatar list for the select avatar dialog.
   */
  getAvailableIcons(): Promise<Array<AvatarIcon>>;

  /**
   * Creates local profile
   */
  createProfile(
      profileName: string, profileColor: number, avatarIndex: number,
      createShortcut: boolean): void;

  /**
   * Sets the local profile name.
   */
  setProfileName(profilePath: string, profileName: string): void;

  /** Records impression of a sign-in promo to metrics. */
  recordSignInPromoImpression(): void;

  /**
   * Gets a profile for which the profile switch screen is shown.
   */
  getSwitchProfile(): Promise<ProfileState>;

  /**
   * Switches to an already existing profile at `profile_path`.
   */
  confirmProfileSwitch(profilePath: string): void;

  /**
   * Cancels the profile switch which aborts the sign-in profile creation
   * flow.
   */
  cancelProfileSwitch(): void;

  // <if expr="lacros">
  /** Gets the available accounts, through WebUIListener. */
  getAvailableAccounts(): void;

  /**
   * Opens Ash Account settings page in a new window.
   */
  openAshAccountSettingsPage(): void;
  // </if>
}

/** @implements {ManageProfilesBrowserProxy} */
export class ManageProfilesBrowserProxyImpl {
  initializeMainView() {
    chrome.send('mainViewInitialize');
  }

  launchSelectedProfile(profilePath: string) {
    chrome.send('launchSelectedProfile', [profilePath]);
  }

  openManageProfileSettingsSubPage(profilePath: string) {
    chrome.send('openManageProfileSettingsSubPage', [profilePath]);
  }

  launchGuestProfile() {
    chrome.send('launchGuestProfile');
  }

  askOnStartupChanged(shouldShow: boolean) {
    chrome.send('askOnStartupChanged', [shouldShow]);
  }

  getNewProfileSuggestedThemeInfo() {
    return sendWithPromise('getNewProfileSuggestedThemeInfo');
  }

  getProfileThemeInfo(theme: UserThemeChoice) {
    return sendWithPromise('getProfileThemeInfo', theme);
  }

  removeProfile(profilePath: string) {
    chrome.send('removeProfile', [profilePath]);
  }

  getProfileStatistics(profilePath: string) {
    chrome.send('getProfileStatistics', [profilePath]);
  }

  loadSignInProfileCreationFlow(profileColor: number|null, gaiaId: string) {
    chrome.send('loadSignInProfileCreationFlow', [profileColor, gaiaId]);
  }

  getAvailableIcons() {
    return sendWithPromise('getAvailableIcons');
  }

  createProfile(
      profileName: string, profileColor: number, avatarIndex: number,
      createShortcut: boolean) {
    chrome.send(
        'createProfile',
        [profileName, profileColor, avatarIndex, createShortcut]);
  }

  setProfileName(profilePath: string, profileName: string) {
    chrome.send('setProfileName', [profilePath, profileName]);
  }

  recordSignInPromoImpression() {
    chrome.send('recordSignInPromoImpression');
  }

  getSwitchProfile() {
    return sendWithPromise('getSwitchProfile');
  }

  confirmProfileSwitch(profilePath: string) {
    chrome.send('confirmProfileSwitch', [profilePath]);
  }

  cancelProfileSwitch() {
    chrome.send('cancelProfileSwitch');
  }

  // <if expr="lacros">
  getAvailableAccounts() {
    chrome.send('getAvailableAccounts');
  }

  openAshAccountSettingsPage() {
    chrome.send('openAshAccountSettingsPage');
  }
  // </if>

  static getInstance(): ManageProfilesBrowserProxy {
    return instance || (instance = new ManageProfilesBrowserProxyImpl());
  }

  static setInstance(obj: ManageProfilesBrowserProxy) {
    instance = obj;
  }
}

let instance: ManageProfilesBrowserProxy|null = null;
